import { Component, OnInit, ElementRef, EventEmitter, Output, Input } from '@angular/core';
import { ElectronService } from '../../providers/electron.service';
import { DiskInfo } from '../../models/diskinfo';
import { BaseComponent } from '../base.component';

/**磁盘id前缀 */
const DISK_PREFFIX = '_logic_disk_';

@Component({
  selector: 'app-disklist',
  templateUrl: './disklist.component.html',
  styleUrls: ['./disklist.component.scss']
})
export class DisklistComponent extends BaseComponent implements OnInit {
  //#region 属性定义
  /**磁盘集合 */
  disks: DiskInfo[];
  /**当前激活的磁盘 */
  currentFocusDisk: DiskInfo;
  /**标识是否正在加载数据 */
  isLoading = true;
  /**异常信息 */
  exception: any;

  /**标识是否自动加载磁盘数据，如果为false需要外部调用tryEnumDisks方法进行磁盘加载 */
  @Input() autoLoad: boolean;
  /**加载前处理事件 */
  @Output() whenBeforeEnumDisks = new EventEmitter();
  /**加载完成事件 */
  @Output() whenEnumDisksCompleted = new EventEmitter<any>();
  /**打开磁盘操作事件 */
  @Output() whenOpenDisk = new EventEmitter<DiskInfo>();
  /**返回上层操作事件 */
  @Output() whenBackPreLevel = new EventEmitter<any>();
  //#endregion

  /**
   * 构造函数
   * @param electronService electron服务实例
   * @param el dom元素
   */
  constructor(electronService: ElectronService, el: ElementRef) {
    super(electronService, el);
  }

  ngOnInit() {
    if (this.autoLoad) {
      this.enumDisks();
    }
  }
  onKeyup(event: KeyboardEvent) {
    const htmlElement = <HTMLElement>event.target;
    let tabIndex = htmlElement.tabIndex;
    const itemsLength = this.disks ? this.disks.length : 0;
    if (event.keyCode === 9) {
      // tab按键处理
      event.preventDefault();
      event.stopImmediatePropagation();
      // 切换tab键盘
      if (event.target) {
        if (tabIndex === -1 && this.currentFocusDisk) {
          tabIndex = this.disks.indexOf(this.currentFocusDisk);
        }
        tabIndex = tabIndex + 1 >= this.disks.length ? 0 : tabIndex + 1;
        this.focusDiskByIndex(tabIndex);
      }
    } else if (event.keyCode === 13) {
      // 回车按键处理
      event.preventDefault();
      event.stopImmediatePropagation();
      // 打开磁盘
      this.openDisk(this.currentFocusDisk);
    } else if ((event.keyCode === 37 || event.keyCode === 39) && itemsLength > 0) {
      // 左、右箭头按键处理
      event.preventDefault();
      event.stopImmediatePropagation();
      // 切换选择项
      let currentIndex = 0;
      currentIndex = this.disks.indexOf(this.currentFocusDisk);
      if (currentIndex >= 0) {
        if (event.keyCode === 37) {
          if (currentIndex - 1 >= 0) {
            currentIndex -= 1;
          }
        } else {
          if (currentIndex + 1 < itemsLength) {
            currentIndex += 1;
          }
        }
      }
      currentIndex = currentIndex < 0 ? 0 : currentIndex;
      // 使指定元素取得焦点
      this.focusDiskByIndex(currentIndex);
    } else if ((event.keyCode === 38 || event.keyCode === 40) && itemsLength > 0) {
      // 上、下箭头按键处理
      event.preventDefault();
      event.stopImmediatePropagation();

      //#region 计算每行显示的列数
      // 计算每行显示的列数
      let lastTop = 0, columnCount = 0;
      for (let index = 0; index < itemsLength; index++) {
        const id = `${DISK_PREFFIX}${index}`;
        const element: HTMLElement = this.getHtmlElementById(id);
        const rect = element.getBoundingClientRect();
        if (index === 0) {
          lastTop = rect.top;
        } else if (lastTop !== rect.top) {
          break;
        }
        columnCount++;
      }
      //#endregion

      // console.log(`itemsLength:${itemsLength},columnCount:${columnCount}`);

      //#region 计算当前移动到的元素索引
      // 计算当前移动到的元素索引
      let currentIndex = -1;
      currentIndex = this.disks.indexOf(this.currentFocusDisk);
      if (currentIndex >= 0) {
        if (event.keyCode === 38) {
          if (currentIndex - columnCount >= 0) {
            currentIndex -= columnCount;
          }
        } else {
          if (currentIndex + columnCount < itemsLength) {
            currentIndex += columnCount;
          }
        }
      }
      currentIndex = currentIndex < 0 ? 0 : currentIndex;
      //#endregion

      // 切换焦点
      this.focusDiskByIndex(currentIndex);
    } else if (event.keyCode === 8) {
      // backspace按键处理（返回上层）
      if (this.whenBackPreLevel) {
        this.whenBackPreLevel.emit(this);
      }
    }
  }
  /**
   * 指定磁盘或的焦点时进行的处理
   * @param disk 待激活的磁盘
   */
  onDiskFocus(disk: DiskInfo) {
    this.currentFocusDisk = disk;
  }
  /**
   * 打开指定磁盘
   * @param disk 待打开的磁盘
   */
  openDisk(disk: DiskInfo) {
    if (disk && this.whenOpenDisk) {
      this.whenOpenDisk.emit(disk);
    }
  }
  /**使容器获得焦点 */
  focusContainer() {
    this.focusElementByClassName('disk-container');
  }
  /**尝试枚举磁盘数据，如果已经存在磁盘数据则不再进行枚举处理 */
  tryEnumDisks() {
    this.enumDisks();
  }
  /**
   * 使页面上指定磁盘元素获取到焦点
   * @param disk 指定磁盘信息
   */
  private focusDisk(disk: DiskInfo) {
    const dIndex = this.disks.indexOf(disk);
    this.focusElement(`${DISK_PREFFIX}${dIndex}`);
  }
  /**
   * 使页面上指定索引的磁盘元素获取到焦点
   * @param disk 指定磁盘信息索引
   */
  private focusDiskByIndex(index: number) {
    this.focusElement(`${DISK_PREFFIX}${index}`);
  }
  /**
   * 枚举逻辑磁盘完成处理
   * @param error 错误信息
   * @param disks 磁盘集合
   */
  private enumDisksCompleted(error: any, disks: DiskInfo[]) {
    this.disks = disks;
    this.exception = error;
    this.isLoading = false;
    if (this.whenEnumDisksCompleted) {
      this.whenEnumDisksCompleted.emit(this);
    }
    // 获取焦点
    this.focusContainer();
  }
  /**
   * 枚举出所有逻辑磁盘信息
   */
  private enumDisks(): void {
    if (!this.disks || this.disks.length === 0) {
      this.isLoading = true;
      this.exception = null;
      // 事件处理
      if (this.whenBeforeEnumDisks) {
        this.whenBeforeEnumDisks.emit(this);
      }
      // 枚举处理
      this.electronService.enumDisks()
      .then(disks => this.enumDisksCompleted(null, disks))
      .catch((error) => this.enumDisksCompleted(error, null));
    } else {
      this.enumDisksCompleted(null, this.disks);
    }
  }
  //#endregion
}
